package com.ruoyi.system.service.impl;

import com.ruoyi.common.utils.data.ListDataRefactor;
import com.ruoyi.system.service.TwUserPullService;
import com.twitter.clientlib.ApiException;
import com.twitter.clientlib.api.TwitterApi;
import com.twitter.clientlib.model.*;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.stream.Collectors;

/**
 * 拉取用户数据
 */
@Service
public class TwUserPullServiceImpl implements TwUserPullService {

    private volatile boolean running = true;

    @Autowired
    private TwCommonServiceImpl twCommonService;

    /**
     * 根据用户id, 获取用户关注者列表
     *
     * @param userId          用户ID
     * @param paginationToken 分页token
     * @return
     */
    @Override
    public List<User> fetchFollowingUsers(String userId, String paginationToken) {
        List<String> ids = this.fetchFollowingIds(userId, paginationToken);
        // 将列表分割，然后遍历获取
        List<List<String>> idsSplitList = ListDataRefactor.averageAssign(ids, 100); //TODO 这个100是每次请求的max_result,整成参数获取
        List<User> userFollowingList = new ArrayList<>(1024);
        idsSplitList.stream().forEach(idList -> {
            // 由于该接口只返回id和user那么,调用接口查询关注者的信息
            List<User> users = this.fetchUserListByIds(idList);
            userFollowingList.addAll(users);
        });
        return userFollowingList;
    }

    /**
     * 根据用户id, 获取用户关注者的ID列表
     *
     * @param userId          用户ID
     * @param paginationToken 分页token
     * @return 关注者的ID列表
     */
    @Override
    public List<String> fetchFollowingIds(String userId, String paginationToken) {
        List<User> users = this.fetchFollowingSingleInfo(userId, paginationToken);
        return users.stream().map(User::getId).collect(Collectors.toList());
    }

    /**
     * 根据用户id, 获取用户关注者的username列表
     *
     * @param userId          用户ID
     * @param paginationToken 分页token
     * @return 关注者的username列表
     */
    @Override
    public List<String> fetchFollowingUsernames(String userId, String paginationToken) {
        List<User> users = this.fetchFollowingSingleInfo(userId, paginationToken);
        return users.stream().map(User::getUsername).collect(Collectors.toList());
    }

    /**
     * 获取用户的关注者列表信息
     *
     * @param userId
     * @param paginationToken
     * @return 用户列表，只能拿到id，username和name
     */
    private List<User> fetchFollowingSingleInfo(String userId, String paginationToken) {
        // 调用用户的关注者API，拉取列表
        UsersFollowingLookupResponse usersFollowingResponse = this.fetchUsersFollowingById(userId, paginationToken);
        List<User> userFollowingList = usersFollowingResponse.getData();

        // 递归获取所有的关注者
        GenericMultipleUsersLookupResponseMeta metaResponse = usersFollowingResponse.getMeta();
        if (StringUtils.isNotEmpty(metaResponse.getNextToken())) {
            List<User> users = this.fetchFollowingUsers(userId, paginationToken);
            userFollowingList.addAll(users);
        }
        return userFollowingList;
    }

    /**
     * 获取用户的关注者，每次请求最多可获取最多1000个
     *
     * @param twUserId
     * @param paginationToken
     * @return
     */
    private UsersFollowingLookupResponse fetchUsersFollowingById(String twUserId, String paginationToken) {
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }
        TwitterApi apiInstance = twCommonService.getTwitterApiByBearerToken();
        // Set the params values
//        String id = "userId"; // String | The ID of the user for whom to return results
        Integer maxResults = 1000; // Integer | The maximum number of results
//        String paginationToken = "paginationToken_example"; // String | This value is populated by passing the 'next_token' or 'previous_token' returned in a request to paginate through results.
        try {
            UsersFollowingLookupResponse result = apiInstance.users().usersIdFollowing(twUserId, maxResults, paginationToken);
            return result;
        } catch (ApiException e) {
            System.err.println("Exception when calling UsersApi#usersIdFollowing");
            System.err.println("Status code: " + e.getCode());
            System.err.println("Reason: " + e.getResponseBody());
            System.err.println("Response headers: " + e.getResponseHeaders());
            e.printStackTrace();
        }
        return new UsersFollowingLookupResponse();
    }

    /**
     * 获取用户列表
     *
     * @param ids 用户ID列表，每次请求最多可获取100个用户名。
     */
    public List<User> fetchUserListByIds(List<String> ids) {
        MultiUserLookupResponse response = this.fetchUsersByIds(ids);
        if (response != null && response.getData() != null) {
            return response.getData();
        } else {
            return new ArrayList<>();
        }
    }

    /**
     * 获取用户列表
     *
     * @param ids 用户ID列表，每次请求最多可获取100个用户名。
     */
    @Override
    public MultiUserLookupResponse fetchUsersByIds(List<String> ids) {
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }
        TwitterApi apiInstance = twCommonService.getTwitterApiByBearerToken();
        // Set the params values
//        List<String> ids = Arrays.asList(); // List<String> | Required. A list of User IDs, comma-separated. You can specify up to 100 IDs.
        Set<String> expansions = new HashSet<>(Arrays.asList()); // Set<String> | A comma separated list of fields to expand.
        Set<String> tweetFields = new HashSet<>(Arrays.asList()); // Set<String> | A comma separated list of Tweet fields to display.
//        Set<String> userFields = new HashSet<>(Arrays.asList()); // Set<String> | A comma separated list of User fields to display.
        Set<String> userFields = new HashSet<>(Arrays.asList(
                "created_at",
                "description",
                "entities,id",
                "location,name",
                "pinned_tweet_id",
                "profile_image_url",
                "protected",
                "public_metrics",
                "url",
                "username",
                "verified",
                "withheld"));
        try {
            MultiUserLookupResponse result = apiInstance.users().findUsersById(ids, expansions, tweetFields, userFields);
            return result;
        } catch (ApiException e) {
            System.err.println("Exception when calling UsersApi#findUsersById");
            System.err.println("Status code: " + e.getCode());
            System.err.println("Reason: " + e.getResponseBody());
            System.err.println("Response headers: " + e.getResponseHeaders());
            e.printStackTrace();
        }
        return new MultiUserLookupResponse();
    }

    /**
     * 获取用户，根据用户名
     *
     * @param username 用户名
     * @return
     */
    @Override
    public MultiUserLookupResponse fetchUserByUsername(String username) {
        MultiUserLookupResponse response = this.fetchUsersByUsernames(username);
        return response.getData().size() > 0 ? response : new MultiUserLookupResponse();
    }

    /**
     * 获取用户列表
     *
     * @param username 用户名，最多可以指定100个用户名。
     * @return
     */
    @Override
    public MultiUserLookupResponse fetchUsersByUsernames(String... username) {
        List<String> usernames = Arrays.asList(username);
        return this.fetchUsersByUsernames(usernames);
    }

    /**
     * 获取用户列表
     *
     * @param usernames 用户名称字符串列表，最多100个
     */
    @Override
    public MultiUserLookupResponse fetchUsersByUsernames(List<String> usernames) {
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }
        TwitterApi apiInstance = twCommonService.getTwitterApiByBearerToken();
        // TODO 参数提出来
        Set<String> expansions = new HashSet<>(Arrays.asList());
        Set<String> tweetFields = new HashSet<>(Arrays.asList());
        Set<String> userFields = new HashSet<>(Arrays.asList(
                "created_at",
                "description",
                "entities,id",
                "location,name",
                "pinned_tweet_id",
                "profile_image_url",
                "protected",
                "public_metrics",
                "url",
                "username",
                "verified",
                "withheld"));
        try {
            MultiUserLookupResponse result = apiInstance.users().findUsersByUsername(usernames, expansions, tweetFields, userFields);
            return result;
        } catch (ApiException e) {
            System.err.println("Exception when calling UsersApi#findUserByUsername");
            System.err.println("Status code: " + e.getCode());
            System.err.println("Reason: " + e.getResponseBody());
            System.err.println("Response headers: " + e.getResponseHeaders());
            e.printStackTrace();
        }
        return new MultiUserLookupResponse();
    }

    @Override
    public void setRunning(boolean running) {
        this.running = running;
    }

    @Override
    public boolean isRunning() {
        return running;
    }

}
